package com.ruoyi.web.controller.common;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.constant.PersonConstants;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.https.HttpUtils;
import com.ruoyi.outpatient.common.MqConstants;
import com.ruoyi.outpatient.core.RedisBloomFilter;
import com.ruoyi.outpatient.domain.*;
import com.ruoyi.outpatient.mapper.IBlogMapper;
import com.ruoyi.outpatient.mapper.ICommentMapper;
import com.ruoyi.outpatient.mapper.IReplyMapper;
import com.ruoyi.outpatient.mapper.ISimilarityMapper;
import com.ruoyi.outpatient.mapper.patient.PatientRegMapper;
import com.ruoyi.outpatient.service.impl.BlogServiceImpl;
import com.ruoyi.outpatient.service.patient.IPatientRegService;
import org.apache.commons.lang3.RandomUtils;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.DefaultTypedTuple;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.temporal.ChronoField;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@SpringBootTest
public class 测试类 {


    @Autowired
    IBlogMapper blogMapper;

    @Autowired
    private RedisCache redisCache;


    @Autowired
    public RedisTemplate redisTemplate;


    @Autowired
    private RecommendTask recommendTask;

    @Autowired
    private RabbitTemplate rabbitTemplate;



    @org.junit.jupiter.api.Test
    public void rabbitaamq() {
//        RedisToMysqlTask toMysqlTask=new RedisToMysqlTask();
//        toMysqlTask.blogLikeToSql();
//        List<Long> list = blogMapper.selectBlogId();
//        System.out.println(list.size());

        //        查看是否过期,如果该key差不多要过期进将他刷新到数据库

        List<Long> longList=blogMapper.selectBlogId();


        Long aLong = redisCache.setCacheIncrement("blog:likesPlusOne:" + 25);
        Long aLong2 = redisCache.setCacheIncrement("blog:likesPlusOne:" + 25);
        Long aLong3 = redisCache.setCacheIncrement("blog:likesPlusOne:" + 25);



        redisCache.expire("blog:likesPlusOne:" + 25,2, TimeUnit.HOURS);
        redisCache.expire("blog:likesPlusOne:" + 26,2, TimeUnit.HOURS);

        HashMap<Long,Long> map=new HashMap<>();

        ArrayList<Long> pastKey=new ArrayList<>();
        int sum=0;
        for (Long lo:longList) {
            Long ttl = redisCache.ttl("blog:likesPlusOne:" + lo, TimeUnit.HOURS);
            System.out.println("时间："+ttl);
//            只要过期时间<3小时就放到新list然后更新到数据库中
            if (ttl>0 && ttl<3){
                Integer cacheObject = (Integer)redisCache.getCacheObject("blog:likesPlusOne:" + lo);
                map.put(lo,Long.valueOf(cacheObject));
//                pastKey.add(sum,lo);
                sum+=1;
            }
        }



        //        获取点赞总数
        Object cacheObject = redisCache.getCacheObject("blog:likesPlusOne:" + 26);
        Long aLong13 = Long.valueOf(cacheObject.toString());
        //        将总数刷新到数据库中

        blogMapper.updateBlogLikes(map);
        System.out.println("redis总数："+aLong);


    }


    @org.junit.jupiter.api.Test
    public void rabbitmq() {


        Blog blog=new Blog();
        blog.setBlogId(3L);

//        监听消息：
//        将交换机 routingkey 新增ID或对象 放入
        rabbitTemplate.convertAndSend(MqConstants.CHAT_EXCHANGE,MqConstants.INSERT_ROUTING_KEY,blog.getBlogId());


    }

    @org.junit.jupiter.api.Test
    public void fortime() {



        recommendTask.ryNoParams();


//        System.out.println(System.currentTimeMillis());
//        for (int i=0;i<10000;i++){
//
//            int sum=0;
//
//            for (int j=0;j<10000;j++){
//
//                if (true){
//                    sum++;
//                }
//            }
//        }
//        System.out.println(System.currentTimeMillis());
//        =1653979665159;
//        System.out.println(());
////        1653979665159    4983
////        1653979664983     176
    }


    @org.junit.jupiter.api.Test
    public void fortimeaa() {

        recommendTask.activeUser();
    }

    @org.junit.jupiter.api.Test
    public void activeUser() {

        String activeUsers = redisCache.getCacheSetstring("活跃用户");
        List<Long> list = JSON.parseArray(activeUsers, Long.class);

        for (Long L:list)
        {
            System.out.println(L);
        }

//        Iterator<ArrayList<Long>> it = activeUsers.iterator();
//        while (it.hasNext()) {
//            ArrayList<Long> str = it.next();
//            System.out.println(str.size());
//        }
////        System.out.println(activeUsers.);
//        Object[] objects = activeUsers.toArray();
//
//        for (int i=0;i<objects.length;i++)
//        {
//            System.out.println(Long.valueOf(objects.toString()));
//        }



    }


//    移位运算
    @org.junit.jupiter.api.Test
    public void activeuser() {


        recommendTask.activeUser();
        long bigsCount = redisCache.getBigsCount("signActiveUser:3:2022:05", 6, 0);
        long i=bigsCount&1;
        System.out.println(bigsCount);
        System.out.println(i); //0

        long l = bigsCount >>> 1;
        System.out.println(l); // 3
    }


    @org.junit.jupiter.api.Test
    public void ndderbdyss() {
//        只要一个月内登录超过5天就是活跃用户
        //        sign:3:2022:4,日期,ture

        Long bitCoun3 = (Long) redisTemplate.execute( (RedisCallback<Long>) con -> con.bitCount("\"sign:3:2022:05\"".getBytes()));


        System.out.println(bitCoun3);

//        String today= DateUtil.today();
//
//        String[] split = today.split("-");
//        System.out.println(split[0]);
//        System.out.println(split[1]);
//        System.out.println(split[2]);
//        System.out.println(Long.valueOf(split[2])-1);
////        不能同时setbin多个,要使用管道
//        redisCache.setBig("sign:"+3+":"+split[0]+":"+split[1],Long.valueOf(split[2]).longValue()-1,true);
//        redisCache.setBig("sign:3:202205",Long.valueOf(split[2])-1,true);
//        redisCache.setBig("sign:3:2022:5",DateUtils.getNowDate().getTime(),true);



    }



    @org.junit.jupiter.api.Test
    public void ndderbdy() {


        Set<ZSetOperations.TypedTuple> set = redisCache.reverseRangeZSetWithScores("recommend:tagscore:3", 0, 3);



//            将该用户的标签转为hashmap
        Map<String,Double> map=new HashMap<>();
        List<Long> list=new ArrayList<>();
        for (ZSetOperations.TypedTuple f:set){
            map.put(f.getValue().toString(),f.getScore());
            list.add(Long.valueOf(f.getValue().toString()));
        }



        System.out.println(set.size());

    }


    /**
     * 附近的人测试
     */
    @org.junit.jupiter.api.Test
    public void ndderby() {

        //        存储位置信息
//        Point point = new Point(110.355529,21.278904);
//        HashMap<Long, String> hashMap = new HashMap<>();
//        hashMap.put(4L, " 岭南师范学院-北1门");
//        redisTemplate.opsForGeo().add("nerby:city:" + 3, point, hashMap);


        //        找出以我为中心距离10公里的位置的人      10             公里
        Distance distances = new Distance(PersonConstants.SCOPE, Metrics.KILOMETERS);
        Circle circle = new Circle(new Point(110.355529,21.278904), distances);
        RedisGeoCommands.GeoRadiusCommandArgs args = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
//        geoRadiusCommandArgs....
        args.includeDistance();

//        args.limit(10);
//        redisTemplate.opsForGeo().radius(circle,12,3);//1:40分钟

        GeoResults<RedisGeoCommands.GeoLocation<String>> geoResults =
                redisCache.radiusGeo("nerby:city:3", circle, args);

        Map<Long,String> map=new HashMap<>();
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> s : geoResults) {
            RedisGeoCommands.GeoLocation<String> content = s.getContent();
            String name = content.getName();

            Distance distance = s.getDistance();
            double value = distance.getValue();
            System.out.println("我距离" + name + "有" + value + "公里");
            String[] idAndLocation = name.split(":");
            map.put(Long.valueOf(idAndLocation[0]),idAndLocation[1]);
        }

    }



//110.355529,21.278904 岭南师范学院-北1门
//    110.307239,21.157362 广东海洋大学
    /**
     * 附近的人测试
     */
    @org.junit.jupiter.api.Test
    public void nerby()  {

//        存储位置信息
        Point point=new Point(112.210719,32.092452);
        redisTemplate.opsForGeo().add("nerby",point,"岭南师范学院");

//        存储详细信息
        Nearby nearby=new Nearby();
        nearby.setLocation("岭南师范学院");
        nearby.setX(112.210719);
        nearby.setX(32.092452);
        redisTemplate.opsForHash().put("nerbymess","岭南师范学院",nearby);





//        返回位置坐标信息
        List<Point> position = redisTemplate.opsForGeo().position("nerby", "岭南师范学院");

        for (Point p:position){
            System.out.println("返回的坐标："+p.getX()+p.getY());
        }



//        计算两个位置之间的距离
        Distance distance = redisTemplate.opsForGeo().distance     //Metrics.KILOMETERS 公里显示
                ("nerby", "岭南师范学院", "广东海洋大学", Metrics.KILOMETERS);
        double value = distance.getValue();
        String unit = distance.getUnit();
//        value：1.32  unit：公里
        new BigDecimal(value).setScale(2);//小数点2位



//        找出以我为中心距离10公里的位置的人
        Distance distances =new Distance(10,Metrics.KILOMETERS);
        Circle circle = new Circle(new Point(112.210719, 32.092452), distances);
        RedisGeoCommands.GeoRadiusCommandArgs geoRadiusCommandArgs = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
//        geoRadiusCommandArgs....
        redisTemplate.opsForGeo().radius(circle,12,3);//1:40分钟




//        按照给定的元素在指定范围查询
        Distance distancess=new Distance(10,Metrics.KILOMETERS);
        RedisGeoCommands.GeoRadiusCommandArgs args=RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        args.includeDistance();
//        GeoResult<RedisGeoCommands.GeoLocation<String>> location=redisTemplate.opsForGeo().radius("outlets","岭南师范学院",distancess,args);


    }




    @org.junit.jupiter.api.Test
    public void esss() throws IOException {
        List<Long> longList = blogMapper.selectBlogId();


        ArrayList<Long> pastKey=new ArrayList<>();
        int sum=0;
        for (Long l:longList) {
//            只要过期时间<3小时则更新到数据库中
            if (l>0 && l<10){

                pastKey.add(sum,l);
                sum+=1;

            }
        }

        for (Long A:pastKey){
            System.out.println("过滤后"+A);
        }

        HashMap<Long,Long> map=new HashMap<>();


        //        获取点赞总数
        Object cacheObject = redisCache.getCacheObject("blog:likesPlusOne:" + 26);
        Long aLong = Long.valueOf(cacheObject.toString());
        System.out.println("redis总数："+aLong);

        map.put(1L,1L);
        map.put(2L,2L);
        map.put(3L,3L);

       int ok= blogMapper.updateBlogLikes(map);

        System.out.println(ok);

    }


    @Autowired
    ICommentMapper commentMapper;
    @Autowired
    IReplyMapper replyMapper;




    /**
     * 测试评论功能
     */
    @org.junit.jupiter.api.Test
    public void order()
    {

        Blog blog=new Blog();

        List<CommentVo> commentVos=new ArrayList<>();
//       1.先找出最热门的前10条评论
        List<Comment> voList= commentMapper.selectHotCommentByBlogId(26L);

        System.out.println(voList);

        for (Comment comment:voList){
            CommentVo commentVo=new CommentVo();
            BeanUtil.copyProperties(comment,commentVo);
            commentVos.add(commentVo);
        }


        //        2.查找最新的评论  封装到List<CommentVo>
        List<Comment> newsList=commentMapper.selectNewsCommentByBlogId(26L);
        for (Comment comment:newsList){
            CommentVo commentVo=new CommentVo();
            BeanUtil.copyProperties(comment,commentVo);
            commentVos.add(commentVo);
        }

        for (Comment vo:voList){
            System.out.println(vo.getCommentLikes()+"mmm评论："+vo.toString());
        }

//        子评论
        List<Reply> replyList = replyMapper.selectReplyListByCommentId(commentVos);




        for (CommentVo vo:commentVos){

            List<Reply> replies=new ArrayList<>();
            for (Reply reply:replyList){
                if (vo.getCommentId().equals(reply.getCommentId())){
                    replies.add(reply);
                }
            }
            vo.setReplyList(replies);
            System.out.println("ddd主评论："+vo.getReplyList());
        }

        for (CommentVo vo:commentVos){

            for (Reply rd:vo.getReplyList()){
                System.out.println(vo.getCommentLikes()+"评论排序求求你："+vo.getCommentId()+" @@ "+rd.getCommentId()+"创建时间："+rd.getCreateTime());
            }
        }




    }



    @org.junit.jupiter.api.Test
    public void random()
    {

        Person person=new Person();
        person.setPersonId(1L);
        person.setPersonName("展示");
        HashMap<String,Person> map=new HashMap<>();
        map.put("person",person);
        redisCaches.setCacheMap("张三",map);

        Object cacheMapFeil =redisCaches.getCacheMap("张三");
        Map<String, Object> map1 = BeanUtil.beanToMap(cacheMapFeil);
        System.out.println(map1.get("person").toString());
        Person person1 = BeanUtil.fillBeanWithMap(map1, new Person(), false);

        System.out.println(person1.toString());

        String s = RandomUtil.randomNumbers(4);
        System.out.println("String:"+s);


        PatientIdentity identity = patientRegService.insertPatientIdentity("441581199708324455", "zhangshanc");
        System.out.println(identity.toString());
    }

    @Autowired
    private IPatientRegService patientRegService;




    @org.junit.jupiter.api.Test
    public void es() throws IOException {
        RestHighLevelClient client=new RestHighLevelClient(RestClient.builder(
           HttpHost.create("http://192.168.202.128:9200")
        ));


        System.out.println(client.ccr()+"dwdwadaw");

//        client.close(); //销毁客户端，释放资源
    }




//    短信验证码
    @org.junit.jupiter.api.Test
    public void sendsms(){

        String host = "https://dfsns.market.alicloudapi.com";
        String path = "/data/send_sms";
        String method = "POST";
        String appcode = "1c2ce6d313204d4bb0d59fb45059c8c5";
        Map<String, String> headers = new HashMap<String, String>();
        //最后在header中的格式(中间是英文空格)为Authorization:APPCODE 83359fd73fe94948385f570e3c139105
        headers.put("Authorization", "APPCODE " + appcode);
        //根据API的要求，定义相对应的Content-Type
        headers.put("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
        Map<String, String> querys = new HashMap<String, String>();
        Map<String, String> bodys = new HashMap<String, String>();
        bodys.put("content", "code:33333");
        bodys.put("phone_number", "13192527463");
        bodys.put("template_id", "TPL_0000");


        try {
            /**
             * 重要提示如下:
             * HttpUtils请从
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/src/main/java/com/aliyun/api/gateway/demo/util/HttpUtils.java
             * 下载
             *
             * 相应的依赖请参照
             * https://github.com/aliyun/api-gateway-demo-sign-java/blob/master/pom.xml
             */
            HttpResponse response = HttpUtils.doPost(host, path, method, headers, querys, bodys);
            System.out.println(response.toString());
            //获取response的body
            //System.out.println(EntityUtils.toString(response.getEntity()));
        } catch (Exception e) {
            e.printStackTrace();
        }

    }




    @Autowired
    private RedisCache redisCaches;
    @org.junit.jupiter.api.Test
    public void randomaa(){
        Person person=new Person();
//        Boolean aBoolean = redisCaches.MysetCacheZSet("recommend:tagscore:" + 3, "后端", 772.0);
        Long tagSumsx = redisCaches.getCacheZSetZCard("recommend:tagscore:" + 3);
        Set<ZSetOperations.TypedTuple> set = redisCaches.reverseRangeZSetWithScores("recommend:tagscore:" + 3, 0, 10);

        ZSetOperations.TypedTuple typedTuple=new DefaultTypedTuple("dw",11.9);
        boolean b = set.contains(typedTuple);
        System.out.println("是否包含"+b);



        Map<String,Double> map=new HashMap<>();
//        Set<ZSetOperations.TypedTuple> typedTupleSet = new HashSet<ZSetOperations.TypedTuple>();
        for (ZSetOperations.TypedTuple f:set){
//            ZSetOperations.TypedTuple typedTuple1 =new DefaultTypedTuple(f,"f.getCreateTime()");
//            typedTupleSet.add(typedTuple1);

            System.out.println("dwa"+f.getValue()+"dw"+f.getScore());
            map.put(f.getValue().toString(),f.getScore());

        }


        Set<String> hashSet=new HashSet<>();
        hashSet.add("后端");
        hashSet.add("前端");

//        hashSet.add("哈哈");
        Double sums=0.0;
        Double mather=0.0;
        Set<String> strings = map.keySet();
        for (String s:strings){
            if (hashSet.contains(s)){
                sums+=map.get(s);
            }
            mather+=Math.pow(map.get(s),2);
        }


        int size = hashSet.size();
        System.out.println("分子："+sums);
        System.out.println("分母左："+mather);
        System.out.println("分母右："+size);
        Double x=sums/((Math.sqrt(mather))*(Math.sqrt(size)));

        System.out.println(Math.sqrt(mather)*Math.sqrt(size));
        System.out.println("相似度为："+x);

        long l = System.currentTimeMillis();
//        for (int i=0;i<1000000;i++){
//            HashMap hashMap=new HashMap();
//            hashMap.containsKey(s);
//            List<Integer> list=new LinkedList<>();
//            list.contains(hashMap.get(1));
//        for (String a:s){
//            if (q.contains(a)){
//            ZSetOperations.TypedTuple typedTuple1 =new DefaultTypedTuple(a,13.0);
//            }
//        }
//        }
        System.out.println("时间为："+(System.currentTimeMillis()-l));

//        前三个月帖子
//        数据库查询出来 select 1.
        System.out.println("啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊");
    }


    @Autowired
    private RedisBloomFilter bloomFilter;

    /**
     * 布隆过滤器+redis 测试
     */
    @org.junit.jupiter.api.Test
    public void buloofiller(){

//        String s="qqaabc";
//        String s="aaaa";
        bloomFilter.init(200000,0.05);
//        bloomFilter.insert("key",s,System.currentTimeMillis()+1000);

        Boolean key = bloomFilter.isBool("key",2L );
        System.out.println("布隆过滤器存在："+key);

    }



    @org.junit.jupiter.api.Test
    public void date(){


        LocalDate now = LocalDate.now();
        int day = now.getDayOfMonth();
        int day1 = now.get(ChronoField.DAY_OF_MONTH);
        System.out.println(day1+":"+day);

    }


    /**
     * set转list
     */
    @org.junit.jupiter.api.Test
    public void setToList(){

      Set<Long> set=new HashSet<>();
      set.add(3L);
      set.add(4L);
      set.add(55L);
      set.add(6L);
        Object[] objects = set.toArray();


        List<Long> list=new ArrayList<>();
        for (int i=0;i<objects.length;i++){
            long l = Long.valueOf(String.valueOf(objects[i]));
            list.add(l);
        }



        for (Long o:list){
            System.out.println("setzhuan:"+o);
        }
    }

    @Autowired
    private ISimilarityMapper similarityMapper;
    /**
     * 获取相似度id列表
     */
    @org.junit.jupiter.api.Test
    public void setTollList(){

        bloomFilter.init(2000,0.01);
        bloomFilter.insert("recommend:bloomFilter:"+3,24L);
        bloomFilter.insert("recommend:bloomFilter:"+3,23L);

        List<Long> blogId= similarityMapper.selectSimilarityId(3L);


//        随机获取10条数据
        List<Long> random=similarityMapper.selectBlogIdByRandom(10);


        for (int i=0;i<blogId.size();i++)
        {
            if (bloomFilter.isBool("recommend:bloomFilter:"+3,blogId.get(i)))
            {
                blogId.remove(i);
                if (StringUtils.isNotNull(random.get(i)))
                {
                    blogId.add(i,random.get(i));
                }

            }
            System.out.println("哈哈哈哈哈哈："+blogId.get(i));
        }


        List<Blog> blogs= blogMapper.selectBlogList(blogId);

        for (Blog b:blogs)
        {
            System.out.println(b.toString());
        }


//        2.与布隆过滤器进行过滤
//        3.将这些过滤的视频放到rabbitmq中，进行删除

//        5.再随机请求30%的帖子

    }
}
